<?php

namespace App\Service;

use App\Extend\Acloud;
use App\Extend\Predis;
use App\Exceptions\ApiException;
use AlibabaCloud\Client\Exception\ClientException;

class SmsService
{
    /**
     * 发送短信验证码
     *
     * @param $mobile
     * @param $ip
     *
     * @return mixed
     *
     * @throws ClientException
     */
    public static function sendCode($mobile, $ip)
    {
        // 验证参数
        throw_if(!preg_match('/^1[345789][0-9]{9}$/', $mobile), new ApiException('手机号格式不正确'));

        // 发送短信风控
        // 同一IP同一手机号，30分钟内发送次数超过10次，此IP拉黑2小时
        $redis = new Predis();
        $ipKey = 'SMS:' . $ip . ':' . $mobile;
        $count = $redis->get($ipKey);
        if ($count > 9) {
            // IP拉黑2小时
            $redis->expire($ipKey, 2 * 60 * 60);

            throw_if(true, new ApiException('发送过于频繁，请稍后重试!!'));
        }

        // 同一手机号，60秒（前端展示的倒计时）内只能发送一次
        $mobileKey = 'SMS:' . $mobile;
        $value     = $redis->get($mobileKey);
        throw_if($value, new ApiException('发送过于频繁，请稍后重试'));

        // 验证码
        $code = rand(100000, 999999);
        $data = ['code' => $code];

        // 发送
        $result = Acloud::sendSms($mobile, 'SMS_169897105', $data);
        throw_if(!$result['status'], new ApiException($result['msg']));

        // 发送成功，记录数据
        $redis->incr($ipKey);
        if (!$count) {
            // 有效期30分钟
            $redis->expire($ipKey, 30 * 60);
        }
        $redis->set($mobileKey, $code, 60);

        return true;
    }

    /**
     * 验证短信验证码
     *
     * @param $mobile
     * @param $code
     *
     * @return mixed
     */
    public static function checkCode($mobile, $code)
    {
        $mobileKey = 'SMS:' . $mobile;
        $redis     = new Predis();
        $value     = $redis->get($mobileKey);
        throw_if(!$value || $value != $code, new ApiException('验证码错误'));

        return true;
    }
}
